template.js ➔ getAbePrecontribFromTemplates   B
last analyzed

Complexity

Conditions 1
Paths 2

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 2
dl 0
loc 26
rs 8.8571
c 0
b 0
f 0
nop 1

1 Function

Rating   Name   Duplication   Size   Complexity  
A template.js ➔ ... ➔ ??? 0 15 3
1
import fse from 'fs-extra'
2
import {Promise} from 'bluebird'
3
import path from 'path'
4
import {
5
  config,
6
  coreUtils,
7
  cmsData,
8
  abeExtend,
9
  cmsTemplates
10
} from '../../'
11
import * as sourceAttr from '../../cms/editor/handlebars/sourceAttr'
12
13
export function getTemplatesAndPartials(templatesPath, partialsPath) {
14
  let allFiles = []
15
  var p = new Promise((resolve) => {
16
    const extension = '.' + config.files.templates.extension
17
    return coreUtils.file.getFilesAsync(templatesPath, true, extension)
18
    .then(function(files){
19
      allFiles = allFiles.concat(files)
20
      return coreUtils.file.getFilesAsync(partialsPath, true, extension)
21
      .then(function(files){
22
        allFiles = allFiles.concat(files)
23
        return resolve(allFiles)
24
      })
25
    })
26
  })
27
28
  return p
29
}
30
31
export function addOrder(text) {
32
  var regAbe = /{{abe[\S\s].*?key=['|"]([\S\s].*?['|"| ]}})/g
33
  var matches = text.match(regAbe)
34
  var order = 0
35
  
36
  if(typeof matches !== 'undefined' && matches !== null){
37
    Array.prototype.forEach.call(matches, (match) => {
38
      if(typeof match !== 'undefined' && match !== null) {
39
        
40
        var orderAttr = cmsData.regex.getAttr(match, 'order')
41
42
        if(typeof orderAttr === 'undefined' || orderAttr === null || orderAttr === '') {
43
          var matchOrder = match.replace(/\}\}$/, ` order='${order}'}}`)
44
          text = text.replace(match, matchOrder)
45
        }
46
        order++
47
      }
48
    })
49
  }
50
  return text
51
}
52
53
export function getAbeImport(text) {
54
  var partials = []
55
  let listReg = /({{abe.*type=[\'|\"]import.*}})/g
56
  var match
57
  while (match = listReg.exec(text)) {
58
    partials.push(match[0])
59
  }
60
61
  return partials
62
}
63
64
export function includePartials(text, json) {
65
  var abeImports = cmsTemplates.template.getAbeImport(text)
66
67
  Array.prototype.forEach.call(abeImports, (abeImport) => {
68
    var obj = cmsData.attributes.getAll(abeImport, {})
69
70
    var file = obj.file
71
    var partial = ''
72
    file = path.join(config.root, config.partials, file)
73
74
    if (file.indexOf('{{') > -1) {
75
      var keys = sourceAttr.getKeys(file)
76
      Array.prototype.forEach.call(keys, (key) => {
77
        try {
78
          var toEval = `${key.replace(/(\[|\.|\])/g, '\\$1')}`
79
          file = file.replace(new RegExp(`\{\{${toEval}\}\}`, 'g'), eval(`json.${key}`))
0 ignored issues
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
80
        }catch(e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
81
        }
82
      })
83
    }
84
    
85
    if(coreUtils.file.exist(file)) {
86
      partial = cmsTemplates.template.includePartials(fse.readFileSync(file, 'utf8'), json)
87
    }
88
    text = text.replace(cmsData.regex.escapeTextToRegex(abeImport, 'g'), partial)
89
  })
90
91
  return text
92
}
93
94
export function translate(text) {
95
  var importReg = /({{abe.*type=[\'|\"]translate.*}})/g
96
97
  var matches = text.match(importReg)
98
  
99
  if(typeof matches !== 'undefined' && matches !== null) {
100
    Array.prototype.forEach.call(matches, (match) => {
101
      var splitedMatches = match.split('{{abe ')
102
103
      Array.prototype.forEach.call(splitedMatches, (splitedMatch) => {
104
        var currentMatch = `{{abe ${splitedMatch}`
105
        if(/({{abe.*type=[\'|\"]translate.*}})/.test(currentMatch)) {
106
          var locale = cmsData.regex.getAttr(currentMatch, 'locale')
107
          var source = cmsData.regex.getAttr(currentMatch, 'source')
108
109
          if (locale.indexOf('{{') === -1) {
110
            locale = `'${locale}'`
111
          }else {
112
            locale = locale.replace(/\{\{(.*?)\}\}/, '$1')
113
          }
114
115
          if (source.indexOf('{{') === -1) {
116
            source = `'${source.replace(/'/g, '\\\'')}'`
117
          }else {
118
            source = source.replace(/\{\{(.*?)\}\}/, '$1')
119
          }
120
121
          // var replace = `{{{i18nAbe ${locale} ${source}}}}`
122
          var replace = currentMatch.replace('{{abe', '{{i18nAbe')
123
          replace = replace.replace(/locale=['|"].*?['|"]/, locale)
124
          replace = replace.replace(/source=['|"].*?['|"]/, source)
125
          replace = replace.replace(/{{i18nAbe.*?}}/, `{{{i18nAbe ${locale} ${source}}}}`)
126
127
          text = text.replace(cmsData.regex.escapeTextToRegex(currentMatch, 'g'), replace)
128
        }
129
      })
130
    })
131
  }
132
133
  return text
134
}
135
136
export function getTemplate (file, json = {}) {
137
  var text = ''
138
139
  // HOOKS beforeGetTemplate
140
  file = abeExtend.hooks.instance.trigger('beforeGetTemplate', file)
141
142
  file = file.replace(path.join(config.root, config.templates.url), '')
143
  file = file.replace(config.root, '')
144
  if (file.indexOf('.') > -1) {
145
    file = file.replace(/\..+$/, '')
146
  }
147
  file = path.join(config.root, config.templates.url, file + '.' + config.files.templates.extension)
148
  if(coreUtils.file.exist(file)) {
149
    text = fse.readFileSync(file, 'utf8')
150
    text = cmsTemplates.template.includePartials(text, json)
151
    text = cmsTemplates.template.translate(text)
152
    text = cmsTemplates.template.addOrder(text)
153
  } else {
154
    text = `[ ERROR ] template ${file} doesn't exist anymore`
155
  }
156
157
  // HOOKS afterGetTemplate
158
  text = abeExtend.hooks.instance.trigger('afterGetTemplate', text)
159
160
  return text
161
}
162
163
export function getVariablesInWhere(where) {
164
  var ar = []
165
166
  if(where.left.column.indexOf('{{') > -1) {
167
    ar.push(where.left.column.replace(/\{\{(.*?)\}\}/, '$1'))
168
  }
169
  else{
170
    ar.push(where.left.column)
171
  }
172
173
  if (where.right.value) {
174
    if (typeof where.right.value === 'string') {
175
      if(where.right.value && where.right.value.indexOf('{{') > -1) {
176
        ar.push(where.right.value.replace(/\{\{(.*?)\}\}/, '$1'))
177
      }
178
    }else {
179
      where.right.value.forEach(function (value) {
180
        if(value.column.indexOf('{{') > -1) {
181
          ar.push(value.column.replace(/\{\{(.*?)\}\}/, '$1'))
182
        }
183
      })
184
    }
185
  }
186
187
  if(where.right.column && where.right.column.indexOf('{{') > -1) {
188
    ar.push(where.right.column.replace(/\{\{(.*?)\}\}/, '$1'))
189
  }
190
191
  return ar
192
}
193
194
/**
195
 * Get columns and where.left ids of a select statement
196
 *
197
 * select title, image from ../ where template=""
198
 *
199
 * return [title, image, template]
200
 * 
201
 * @param  {Array} templatesList ["article.html", "other.html"]
0 ignored issues
show
Documentation introduced by
The parameter templatesList does not exist. Did you maybe forget to remove this comment?
Loading history...
202
 * @return {Promise}
203
 */
204
export function recurseWhereVariables (where) {
205
  var ar = []
0 ignored issues
show
Unused Code introduced by
The assignment to variable ar seems to be never used. Consider removing it.
Loading history...
206
  var arLeft
207
  var arRight
208
  switch(where.operator) {
209
  case 'AND':
210
    arLeft = cmsTemplates.template.recurseWhereVariables(where.left)
211
    arRight = cmsTemplates.template.recurseWhereVariables(where.right)
212
    return arLeft.concat(arRight)
213
    break
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
214
  case 'OR':
215
    arLeft = cmsTemplates.template.recurseWhereVariables(where.left)
216
    arRight = cmsTemplates.template.recurseWhereVariables(where.right)
217
    return arLeft.concat(arRight)
218
    break
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
219
  default:
220
    ar = getVariablesInWhere(where)
221
    break
222
  }
223
224
  return ar
225
}
226
227
export function getTemplatesTexts(templatesList, json) {
228
  var templates = []
229
  var p = new Promise((resolve) => {
230
    Array.prototype.forEach.call(templatesList, (file) => {
231
      var template = fse.readFileSync(file, 'utf8')
232
      template = cmsTemplates.template.includePartials(template, json)
233
      var name = file.replace(path.join(config.root, config.templates.url, path.sep), '').replace(`.${config.files.templates.extension}`, '')
234
      templates.push({
235
        name: name,
236
        path: file,
237
        template: template
238
      })
239
    })
240
    resolve(templates)
241
  })
242
243
  return p
244
}
245
246
export function execRequestColumns(tpl) {
247
  var ar = []
248
  var matches = cmsData.regex.getTagAbeTypeRequest(tpl)
249
  Array.prototype.forEach.call(matches, (match) => {
250
    var obj = cmsData.attributes.getAll(match[0], {})
251
    var type = cmsData.sql.getSourceType(obj.sourceString)
252
    switch (type) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
253
    case 'request':
254
      var request = cmsData.sql.handleSqlRequest(obj.sourceString, {})
255
      if(typeof request.columns !== 'undefined' && request.columns !== null) {
256
        Array.prototype.forEach.call(request.columns, (column) => {
257
          ar.push(column)
258
        })
259
      }
260
      if(typeof request.where !== 'undefined' && request.where !== null) {
261
        ar = ar.concat(cmsTemplates.template.recurseWhereVariables(request.where))
262
      }
263
    }
264
  })
265
266
  return ar
267
}
268
269
export function getAbeRequestWhereKeysFromTemplates(templatesList) {
270
  var whereKeys = []
271
  var p = new Promise((resolve) => {
272
    Array.prototype.forEach.call(templatesList, (file) => {
273
      whereKeys = whereKeys.concat(cmsTemplates.template.execRequestColumns(file.template))
274
    })
275
    whereKeys = whereKeys.filter(function (item, pos) {return whereKeys.indexOf(item) == pos})
276
    resolve(whereKeys)
277
  })
278
279
  return p
280
}
281
282
export function setAbeSlugDefaultValueIfDoesntExist(templateText) {
283
  var matches = cmsData.regex.getTagAbeWithType(templateText, 'slug')
284
  if(matches == null || matches[0] == null) {
285
    templateText = `{{abe type="slug" source="{{name}}"}}\n${templateText}`
286
  }
287
288
  return templateText
289
}
290
291
export function getAbeSlugFromTemplates(templatesList) {
292
  var slugs = {}
293
  Array.prototype.forEach.call(templatesList, (file) => {
294
    var templateText = cmsTemplates.template.setAbeSlugDefaultValueIfDoesntExist(file.template)
295
    var matchesSlug = cmsData.regex.getTagAbeWithType(templateText, 'slug')
296
    var obj = cmsData.attributes.getAll(matchesSlug[0], {})
297
    slugs[file.name] = obj.sourceString
298
  })
299
  return slugs
300
}
301
302
export function setAbePrecontribDefaultValueIfDoesntExist(templateText) {
303
  var matches = cmsData.regex.getTagAbeWithTab(templateText, 'slug')
304
  if(matches == null || matches[0] == null) {
305
    templateText = `{{abe type='text' key='name' desc='Name' required="true" tab="slug" visible="false"}}\n${templateText}`
306
  }
307
308
  return templateText
309
}
310
311
export function getAbePrecontribFromTemplates(templatesList) {
312
  var fields = []
313
  var precontributionTemplate = ''
314
  Array.prototype.forEach.call(templatesList, (file) => {
315
    var slugMatch = cmsData.regex.getTagAbeWithType(file.template, 'slug')
316
    var templateText = file.template
317
    if(slugMatch == null || slugMatch[0] == null) {
318
      templateText = cmsTemplates.template.setAbePrecontribDefaultValueIfDoesntExist(file.template)
319
    }
320
321
    var matchesTabSlug = cmsData.regex.getTagAbeWithTab(templateText, 'slug')
322
    Array.prototype.forEach.call(matchesTabSlug, (match) => {
323
      fields.push(cmsData.attributes.getAll(match, {}))
324
      var tag = match.replace(/\}\}$/, ' precontribTemplate="' + file.name + '"}}')
325
      tag = tag.replace(/(key=[\'|\"])(.*?)([\'|\"])/, '$1/' + file.name + '/$2$3')
326
      precontributionTemplate += `${tag}\n`
327
    })
328
  })
329
330
  precontributionTemplate = cmsTemplates.template.addOrder(precontributionTemplate)
331
332
  return {
333
    fields: fields,
334
    template: precontributionTemplate
335
  }
336
}
337
338
export function getStructureAndTemplates() {
339
  const pathStructure = path.join(config.root, config.structure.url)
340
  const pathTemplates = path.join(config.root, config.templates.url)
341
  const extension = '.' + config.files.templates.extension
342
  let result = {'structure': [], 'templates': []}
343
344
  result.structure = coreUtils.file.getFoldersSync(pathStructure, true)
345
  let templatePaths = coreUtils.file.getFilesSync(pathTemplates, true, extension)
346
  Array.prototype.forEach.call(templatePaths, (templatePath) => {
347
    let additionalPath = path.dirname(templatePath).replace(pathTemplates,'')
348
    if(additionalPath !== '') additionalPath = additionalPath.substring(1)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
349
    let name = path.join(additionalPath,path.basename(templatePath,extension))
350
    let template = {'path':templatePath, 'name':name}
351
    result.templates.push(template)
352
  })
353
354
  return result
355
}